package com.googlecode.jlogindexer.log4j;

/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software
 * License version 1.1, a copy of which has been included with this
 * distribution in the LICENSE.txt file.  */

// Contributors:   Mathias Bogaert

import org.apache.log4j.helpers.Transform;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.xml.XMLLayout;

/**
* This is the exact copy of XMLLayout from Apache log4j customized in the format method alone.
 * */
public class JXMLLayout extends XMLLayout {

  private  final int DEFAULT_SIZE = 256;
  private final int UPPER_LIMIT = 2048;

  private StringBuffer buf = new StringBuffer(DEFAULT_SIZE);
 

  /**
   * Formats a {@link LoggingEvent} in conformance with the log4j.dtd.
   * */
  public String format(LoggingEvent event) {

    // Reset working buffer. If the buffer is too large, then we need a new
    // one in order to avoid the penalty of creating a large array.
    if(buf.capacity() > UPPER_LIMIT) {
      buf = new StringBuffer(DEFAULT_SIZE);
    } else {
      buf.setLength(0);
    }
    
    // We yield to the \r\n heresy.

    buf.append("<event logger=\"");
    buf.append(event.getLoggerName());
    buf.append("\" timestamp=\"");
    buf.append(event.timeStamp);
    buf.append("\" level=\"");
    buf.append(event.getLevel());
    buf.append("\" thread=\"");
    buf.append(event.getThreadName());
    buf.append("\">\r\n");

    buf.append("<message><![CDATA[");
    // Append the rendered message. Also make sure to escape any
    // existing CDATA sections.
    Transform.appendEscapingCDATA(buf, event.getRenderedMessage());
    buf.append("]]></message>\r\n");       
    
    String ndc = event.getNDC();
    if(ndc != null) {
      buf.append("<NDC><![CDATA[");
      buf.append(ndc);
      buf.append("]]></NDC>\r\n");       
    }
    
    String[] s = event.getThrowableStrRep();
    if(s != null) {
      buf.append("<throwable><![CDATA[");
      for(int i = 0; i < s.length; i++) {
	buf.append(s[i]);
	buf.append("\r\n");
      }
      buf.append("]]></throwable>\r\n");
    }
    
    	//Always show location info
	  LocationInfo locationInfo = event.getLocationInformation();	
	  buf.append("<locationInfo class=\"");
	  buf.append(locationInfo.getClassName());
	  buf.append("\" method=\"");
	  buf.append(Transform.escapeTags(locationInfo.getMethodName()));
	  buf.append("\" file=\"");
	  buf.append(locationInfo.getFileName());
	  buf.append("\" line=\"");
	  buf.append(locationInfo.getLineNumber());
	  buf.append("\"/>\r\n");
    
    buf.append("</event>\r\n\r\n");
    
    return buf.toString();
  }
  
  /**
     The XMLLayout prints and does not ignore exceptions. Hence the
     return value <code>false</code>.
  */
  public boolean ignoresThrowable() {
    return false;
  }
}

